<template>
  <view class="page">
    <!-- 聊天记录 -->
    <scroll-view
      class="scroll"
      :scroll-y="scrollY"
      :scroll-top="top"
      :scroll-into-view="view"
      @scroll="onScroll"
      scroll-with-animation
    >
      <view class="content" :style="{ 'padding-bottom': contentBottom + 'rpx' }">
        <image class="bg" src="https://ainengli.hzjrsw.com/jkhx/answerBg.png"></image>
        <view class="tips">
          <view class="text">您的本次信息严格保密，请放心填写</view>
        </view>
        <view class="messages">
          <template v-for="(item, index) of List" :key="index">
            <view
              class="message"
              :id="['message_' + index]"
              :style="{
                flexDirection: 'row'
              }"
            >
              <view class="question">
                <image class="robot" src="@/static/image/raozg/robot.png"></image>
                <view class="text">
                  <flow-text
                    :text="item.questionName"
                    :state="current > index ? 'stop' : ''"
                    @onStop="TextStop(index)"
                  ></flow-text>
                </view>
              </view>
            </view>
            <view
              v-if="item.chosen"
              class="message"
              :style="{
                flexDirection: 'row-reverse'
              }"
            >
              <view class="answer">
                <image class="edit" @tap="edit(index)" src="@/static/image/edit.png"></image>
                <text>{{ item.chosen }}</text>
              </view>
            </view>
          </template>
        </view>
        <!-- <view class="question">
          <image class="robot" src="@/static/image/raozg/robot.png"></image>
          <view class="dialog"> 调研完成，点击生成<view class="green">健康画像 </view></view>
        </view> -->
      </view>
    </scroll-view>
    <view class="footer" :style="{ bottom: bottom + 'px' }" v-if="answer.show">
      <view class="answer_box">
        <view v-if="List[current].questionType.includes('单选')" class="tags">
          <view
            v-for="(item, index) of List[current].options"
            :key="index"
            class="tag"
            :class="{ active: answer.sort == item.sort }"
            @tap="select(item, 'single')"
          >
            {{ item.label }}
          </view>
        </view>
        <view v-else-if="List[current].questionType.includes('单选')" class="tags">
          <view
            v-for="(item, index) of List[current].options"
            :key="index"
            class="tag"
            :class="{ active: answer.sort.includes(item.sort) }"
            @tap="select(item, 'multiple', List[current].options)"
          >
            {{ item.label }}
          </view>
        </view>
        <input
          v-else
          v-model="answer.value"
          class="inputs"
          placeholder="请填写回答"
          :adjustPosition="false"
          @focus="onFocus"
          @blur="onBlur"
          @confirm="confirm"
          confirm-type="done"
        />
        <!-- <input v-else v-model="answer.value" class="inputs" placeholder="请填写回答" /> -->
      </view>
      <view class="btns">
        <button class="button" :disabled="!answer.value" @tap="confirm">确定</button>
      </view>
    </view>
    <view class="footer" v-else-if="current >= List.length">
      <view class="btns">
        <button class="button" @tap="submit">进入我的健康画像</button>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import FlowText from '@/components/FlowText.vue'
import { onLoad } from '@dcloudio/uni-app'
import { ref, reactive, nextTick } from 'vue'
// import { data } from './data.js'
import { debounce, throttle, typeOf } from '@/utils/tools'
import store from '@/store'
import { saveScale } from '@/api/dataFix'

const scrollY = ref(true)
const view = ref('')

const page = ref(0)
const bottom = ref(0)

const contentBottom = ref(586)
// const diff = ref(0)
const onFocus = (e) => {
  console.log(store.state.platform)
  if (store.state.platform === 'android') {
    scrollY.value = false
  }
  const query = uni.createSelectorQuery()
  query
    .select('.inputs')
    .boundingClientRect((data) => {
      const diff = page.value - data.bottom
      if (e.detail.height < diff) {
        bottom.value = 0
      } else {
        bottom.value = e.detail.height - diff
        contentBottom.value = 586 + bottom.value

        nextTick(() => {
          view.value = 'message_' + current.value
          // scrollToBottom(bottom.value)
        })
      }
    })
    .exec()
}
const onBlur = () => {
  scrollY.value = true
  bottom.value = 0
  contentBottom.value = 586
  // if (!bottom.value) {
  //   return
  // }
  nextTick(() => {
    view.value = ''
    // scrollToBottom(bottom.value * -1)
    // bottom.value = 0
  })
}

const top = ref(0)
const oldTop = ref(0)
const onScroll = debounce((e) => {
  oldTop.value = e.target.scrollTop
  view.value = ''
}, 200)
const current = ref(0)
const List = ref([])

let Data = ref([])

const answer = ref({
  show: false,
  loading: true,
  sort: '',
  value: ''
})

const TextStop = (index) => {
  console.log(index)
  if (index === current.value) {
    answer.value.show = true
    answer.value.loading = false
    scrollToBottom()
  }
}

const scrollHeight = ref(0)
const contentHeight = ref(0)

const getHeight = (str) => {
  return new Promise((resolve, reject) => {
    const query = uni.createSelectorQuery()
    query
      .select(str)
      .boundingClientRect((data) => {
        resolve(data.height)
      })
      .exec()
  })
}

const scrollToBottom = debounce((diff) => {
  top.value = oldTop.value
  nextTick(() => {
    if (!diff) {
      getHeight('.content').then((height) => {
        contentHeight.value = height

        nextTick(() => {
          top.value = contentHeight.value - scrollHeight.value
          oldTop.value = top.value
        })
      })
    } else {
      nextTick(() => {
        top.value = top.value + diff
        oldTop.value = top.value
      })
    }
  })
}, 200)

const loop = (obj, d) => {
  if (obj.operator === 'AND') {
    return obj.conditions.every((v) => {
      if (typeOf(v) === 'array') {
        if (typeOf(d[v[0]]) === 'array') {
          if (d[v[0]].includes(v[1])) {
            return true
          }
        } else {
          if (d[v[0]] === v[1]) {
            return true
          }
        }
      } else if (typeOf(v) === 'object') {
        return loop(v, d)
      }
    })
  } else if (obj.operator === 'OR') {
    return obj.conditions.some((v) => {
      if (typeOf(v) === 'array') {
        if (typeOf(d[v[0]]) === 'array') {
          if (d[v[0]].includes(v[1])) {
            return true
          }
        } else {
          if (d[v[0]] === v[1]) {
            return true
          }
        }
      } else if (typeOf(v) === 'object') {
        return loop(v, d)
      }
    })
  }
  return true
}

const showCondition = (arr) => {
  const obj = {}
  arr.map((v) => {
    obj[v.questionCode] = v.sort
  })

  return arr.filter((v) => {
    if (!v.showCondition) {
      return true
    }
    return loop(v.showCondition, obj)
  })
}

const contrast = (o, n) => {
  const oData = JSON.parse(o)
  const nData = JSON.parse(n)

  // let index = nData.length - 1
  let index = -1
  for (let i = 0; i < nData.length; i++) {
    // if (!nData[i].chosen || i >= oData.length || nData[i].questionCode !== oData[i].
    if (!nData[i].chosen) {
      index = i
      break
    }
  }
  console.log(index)
  return index
}

const verification = (rule) => {
  return new Promise((resolve, reject) => {
    if (rule.type === 'integer') {
      let flag = true
      if (answer.value.value.match(/^[0-9]*$/)) {
        if (rule.min || rule.min === 0) {
          if (answer.value.value >= rule.min) {
          } else {
            flag = false
          }
        }
        if (rule.max) {
          if (answer.value.value < rule.max) {
          } else {
            flag = false
          }
        }
      } else {
        flag = false
      }
      if (flag) {
        resolve()
      } else {
        reject(rule.message)
      }
    } else if (rule.type === 'RegExp') {
      const pattern = rule.pattern.split('/')
      const reg = new RegExp(pattern[1], pattern[3] ? pattern[3] : '')
      if (reg.test(answer.value.value)) {
        resolve()
      } else {
        reject(rule.message)
      }
    }
  })
}

const confirm = throttle(async () => {
  if (List.value[current.value].rules && List.value[current.value].rules.length) {
    try {
      const rules = List.value[current.value].rules
      for (let i = 0; i < rules.length; i++) {
        const rule = rules[i]
        await verification(rule)
      }
    } catch (e) {
      console.log(e)
      uni.showModal({
        title: '提示',
        content: e,
        showCancel: false,
        success: function (res) {
          if (res.confirm) {
            console.log('用户点击确定')
          }
        }
      })
      return
    }
  }

  const o = JSON.stringify(List.value)
  List.value[current.value].chosen = answer.value.value
  List.value[current.value].sort = answer.value.sort

  const L = showCondition(Data.value)
  const n = JSON.stringify(L)

  const index = contrast(o, n)
  if (current.value !== index && index !== -1) {
    current.value = index
    if (List.value.length === current.value + 1) {
      List.value = L.slice(0, current.value + 1)
      answer.value.show = true
      answer.value.loading = false
    } else {
      List.value = L.slice(0, current.value + 1)
      answer.value.show = false
      answer.value.loading = false
    }
    answer.value.sort = List.value[current.value].sort
    answer.value.value = List.value[current.value].chosen
  } else {
    answer.value.show = false
    answer.value.loading = false
    current.value = n.length
  }
  scrollToBottom()
}, 500)

const select = (item, type, options) => {
  if (type === 'single') {
    answer.value.sort = item.sort
    answer.value.value = item.label
  } else {
    if (answer.value.sort.includes(item.sort)) {
      answer.value.sort = answer.value.value.filter((v) => v !== item.sort)
    } else {
      answer.value.sort.push(item.sort)
    }
    answer.value.value = options.reduce((p, c) => {
      if (answer.value.sort.includes(c.sort)) {
        if (!p) {
          return c.label
        } else {
          return p + '、' + c.label
        }
      }
    }, '')
  }
}

const edit = (index) => {
  if (answer.value.loading) {
    return
  }
  current.value = index
  // if (current.value === List.value.length - 1 && List.value[current.value].chosen) {
  // } else {
  answer.value.sort = List.value[current.value].sort
  answer.value.value = List.value[current.value].chosen
  answer.value.show = true
  view.value = 'message_' + current.value
  // }
}

const submit = throttle(() => {
  console.log(store.state.dataFix.DATA)

  const { empi, scaleCode } = store.state.dataFix.DATA

  // const m = deepCopy(questions)
  // m.map(v => {
  //   v['showCondition'] = null;
  //   v['options'] = null;
  //   v['rules'] = null;
  // })

  const params = {
    empi,
    scaleCode,
    answers: JSON.stringify(List.value),
    isFinish: true
  }
  uni.showLoading({
    title: '正在生成健康画像...'
  })

  saveScale(params)
    .then((res) => {
      uni.hideLoading()
      console.log('提交成功')
      uni.reLaunch({ url: '/pages/body/index' })
    })
    .catch((err) => {
      console.log(err)
      uni.hideLoading()
    })
}, 500)

onLoad(() => {
  Data.value = store.state.dataFix.DATA.questions

  const arr = showCondition(Data.value)
  const Index = arr.findIndex((v) => {
    return !v.chosen
  })
  if (Index === -1) {
    current.value = arr.length
    List.value = showCondition(Data.value).slice(0, current.value)
    answer.value.loading = false
  } else {
    current.value = Index
    List.value = showCondition(Data.value).slice(0, Index + 1)

    answer.value.sort = List.value[current.value].sort
    answer.value.value = List.value[current.value].chosen
  }

  nextTick(() => {
    getHeight('.page').then((height) => {
      page.value = height
    })
    getHeight('.scroll').then((height) => {
      scrollHeight.value = height

      scrollToBottom()
    })
  })
})
</script>

<style lang="scss" scoped>
.page {
  box-sizing: border-box;
  width: 100vw;
  height: 100vh;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  position: relative;
}
.scroll {
  box-sizing: border-box;
  width: 100vw;
  height: 100%;
  position: relative;
}
.content {
  width: 750rpx;
  box-sizing: border-box;
  padding-bottom: 586rpx;
  .bg {
    position: absolute;
    left: 0;
    top: 0;
    width: 750rpx;
    height: 522rpx;
    z-index: -1;
  }
  .tips {
    // position: fixed;
    // top: 0;
    // left: 0;
    width: 750rpx;
    padding: 24rpx 32rpx 0 32rpx;
    .text {
      width: 686rpx;
      height: 60rpx;
      background: rgba(255, 255, 255, 0.6);
      border-radius: 12rpx 12rpx 12rpx 12rpx;
      border: 1px solid #ffffff;
      font-weight: 400;
      text-align: center;
      font-size: 24rpx;
      color: #666666;
      line-height: 60rpx;
    }
  }
  .question {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    .robot {
      flex: 0 0 auto;
      width: 122rpx;
      height: 122rpx;
    }
    .text {
      margin-top: -30rpx;
      padding: 24rpx;
      background: #ffffff;
      border-radius: 4rpx 24rpx 24rpx 24rpx;
      font-weight: 400;
      font-size: 30rpx;
      color: #222222;
      line-height: 54rpx;
      .green {
        display: inline-block;
        color: #00d1b6;
      }
    }
  }
  .messages {
    margin-top: 32rpx;
  }
  .message {
    &:not(:first-child) {
      margin-top: 48rpx;
    }
    display: flex;
    padding: 0 32rpx;
  }
  .answer {
    background: #00d1b6;
    border-radius: 24rpx 0px 24rpx 24rpx;
    padding: 24rpx;
    font-weight: 400;
    font-size: 30rpx;
    color: #ffffff;
    line-height: 42rpx;
    text-align: right;
    position: relative;
    display: inline-flex;
    word-break: break-all;
    .edit {
      flex: 0 0 auto;
      height: 40rpx;
      width: 40rpx;
      margin-right: 20rpx;
      line-height: 42rpx;
    }
  }
}
.footer {
  position: absolute;
  width: 100%;
  left: 0;
  bottom: 0;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  background: #fff;
  .answer_box {
    max-height: 520rpx;
    overflow: hidden auto;
    padding: 32rpx;
    box-sizing: border-box;
    .tags {
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      gap: 24rpx;
      .tag {
        background: #ffffff;
        border-radius: 36rpx;
        border: 1px solid #cfcfcf;
        font-weight: 400;
        font-size: 30rpx;
        color: #222222;
        padding: 16rpx 32rpx;
        box-sizing: border-box;
      }
      .active {
        background: #00d1b6;
        border: 1px solid #00d1b6;
        color: #ffffff;
      }
    }
    .inputs {
      border-radius: 36rpx;
      border: 1rpx solid #cfcfcf;
      font-weight: 400;
      font-size: 30rpx;
      line-height: 30rpx;
      color: #222222;
      padding: 18rpx 32rpx;
      ::v-deep .uni-input-placeholder {
        color: #cccccc;
      }
    }
  }
  .btns {
    height: 136rpx;
    padding: 24rpx 32rpx;
    box-sizing: border-box;
    display: flex;
    justify-content: space-between;
    gap: 16rpx;
    .button {
      background: #00d1b6;
      width: 686rpx;
      height: 88rpx;
      border-radius: 44rpx;
      font-family:
        PingFang SC,
        PingFang SC;
      font-weight: 500;
      font-size: 32rpx;
      color: #ffffff;
      text-align: center;
      line-height: 88rpx;
    }
  }
}
</style>
